import { director } from "cc";

export class GlobalUniformMgr {
    private static _inst: GlobalUniformMgr = null;
    public static get inst(): GlobalUniformMgr {
        if (this._inst == null) {
            this._inst = new GlobalUniformMgr();
        }
        return this._inst;
    }

    private _globalUniformMap = {};
    constructor() {
        let pipelineUBO = director.root.pipeline.pipelineUBO as any;
        let globalUBO = pipelineUBO._globalUBO;
        let cameraUBO = pipelineUBO._cameraUBO;

        //w 空闲
        let GLOBAL_UBO_TIME_OFFSET = 0;
        this._globalUniformMap['cc_time.w'] = { ubo: globalUBO, offset: GLOBAL_UBO_TIME_OFFSET + 3 };

        //w 空闲
        let CAMERA_UBO_GLOBAL_FOG_BASE_OFFSET = 128;
        this._globalUniformMap['cc_fogBase.w'] = { ubo: cameraUBO, offset: CAMERA_UBO_GLOBAL_FOG_BASE_OFFSET + 3 };

        //w 空闲
        let CAMERA_UBO_GLOBAL_FOG_ADD_OFFSET = 132;
        this._globalUniformMap['cc_fogAdd.w'] = { ubo: cameraUBO, offset: CAMERA_UBO_GLOBAL_FOG_ADD_OFFSET + 3 };

        //zw 空闲
        let CAMERA_UBO_NEAR_FAR_OFFSET = 136;
        this._globalUniformMap['cc_nearFar.z'] = { ubo: cameraUBO, offset: CAMERA_UBO_NEAR_FAR_OFFSET + 2 };
        this._globalUniformMap['cc_nearFar.w'] = { ubo: cameraUBO, offset: CAMERA_UBO_NEAR_FAR_OFFSET + 3 };
    }

    resetAll() {
        let keys = Object.keys(this._globalUniformMap);
        for (let i = 0; i < keys.length; ++i) {
            let key = keys[i];
            let uniformInfo: { ubo: any, offset: number } = this._globalUniformMap[key];
            uniformInfo.ubo[uniformInfo.offset] = 0;
        }
    }

    setGlobalUniform(name: string, value: number) {
        let uniformInfo: { ubo: any, offset: number } = this._globalUniformMap[name];
        if (uniformInfo == null) {
            console.log('can not find the global uniform info by given name:' + name);
            console.log('please use one of ' + Object.keys(this._globalUniformMap).join(','));
        }
        uniformInfo.ubo[uniformInfo.offset] = value;
    }

    getGlobalUniform(name: string): number {
        let uniformInfo: { ubo: any, offset: number } = this._globalUniformMap[name];
        if (uniformInfo == null) {
            console.log('can not find the global uniform info by given name:' + name);
            console.log('please use one of ' + Object.keys(this._globalUniformMap).join(','));
        }
        return uniformInfo.ubo[uniformInfo.offset] || 0;
    }
}